# -*- coding:utf-8 -*-
# Python 3.4

from tkinter import *
from tkinter import ttk
import smtplib
from tkinter import messagebox
from email.header import Header
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
from email.utils import parseaddr, formataddr
from email.encoders import encode_base64
import tkinter.filedialog as fd

class Smtp():
    def __init__(self, root):

        # 分为三部分
        self.Header = Frame(root, width=50, height=50)
        self.Header.grid(row=0, column=0)
        self.Body = Frame(root, width=50, height=60)
        self.Body.grid(row=1, column=0)
        self.Foot = Frame(root, width=50)
        self.Foot.grid(row=2, column=0)

        # 发件人信息
        self.From_addr = ttk.Label(self.Header, text='发件人')
        self.From_addr.grid(row=0, column=0)
        self.From_addr_text = ttk.Entry(self.Header)
        self.From_addr_text.grid(row=0, column=1)
        self.FromserverChosen = ttk.Combobox(self.Header, width=9)
        self.FromserverChosen['values'] = ('@qq.com', '@139.com', '@163.com')     # 设置下拉列表的值
        self.FromserverChosen.grid(row=0, column=2)
        self.FromserverChosen.current(0)
        self.From_pw = ttk.Label(self.Header, text='密   码')
        self.From_pw.grid(row=1, column=0)
        self.password = StringVar()
        self.From_pw_text = ttk.Entry(self.Header, textvariable=self.password, show='*')
        self.From_pw_text.grid(row=1, column=1)
        self.btn = ttk.Button(self.Header, text='Auth', command=self.authentication)
        self.btn.grid(row=1, column=2)

        # 收件人邮件地址
        self.To_addr = ttk.Label(self.Header, text='收件人')
        self.To_addr.grid(row=2, column=0)
        self.To_addr_text = ttk.Entry(self.Header)
        self.To_addr_text.grid(row=2, column=1)
        self.Toserver = ttk.Combobox(self.Header, width=9)
        self.Toserver['values'] = ('@qq.com', '@139.com', '@163.com')
        self.Toserver.grid(row=2, column=2)
        self.Toserver.current(0)

        # 构建主题Entry框
        self.subject_label = ttk.Label(self.Header, text='主   题')
        self.subject_label.grid(row=3, column=0)
        self.subject_text = ttk.Entry(self.Header, width=32)
        self.subject_text.grid(row=3, column=1, columnspan=2)

        # 构建发送内容控件
        self.content = Text(self.Body, width=40)
        self.content.grid(row=0, column=0)

        # 重置按钮
        self.reset = ttk.Button(self.Foot, text='重置按钮', command=self._init_send)
        self.reset.grid(row=0, column=0)

        # 添加附件
        self.attachment = ttk.Button(self.Foot, text='添加附件', command=self.Addattach)
        self.attachment.grid(row=0, column=1)

        # 发送按钮
        self.send = ttk.Button(self.Foot, text='Send', command=self.send)
        self.send.grid(row=0, column=3)
        self._init_send()

    # 清空所有的内容
    def _init_send(self):
        self.msg = MIMEMultipart('alternative')
        self.From_addr_text.delete(0, END)
        self.From_pw_text.delete(0, END)
        self.To_addr_text.delete(0, END)
        self.subject_text.delete(0, END)
        self.content.delete(0.0, END)


    # 进行验证账号是否可以使用本软件进行发送邮件
    def authentication(self):
        try:
            self.port = 'smtp.' + str(self.FromserverChosen.get())[1:].split('.')[0] + '.com'
            print(self.port)
            server = smtplib.SMTP(self.port, 25)
            server.set_debuglevel(True)
            server.starttls()
            server.login(self.From_addr_text.get() + self.FromserverChosen.get(), self.From_pw_text.get())
            messagebox.showinfo('验证成功', '恭喜您的账号和密码正确，可以进行发送邮件')
        except smtplib.SMTPAuthenticationError:
            messagebox.showerror('验证失败', '如果确保用户名和密码正确，那么请打开邮箱的SMTP服务器！！！')

    # 添加附件
    def Addattach(self):
        filepath = fd.askopenfilename()
        import os
        filesize = os.path.getsize(filepath) / 1024 /1024  # 得到需要发送文件的大小，并将其单位换算为Mb。
        # 判断文件的大小
        if filesize > 2:
            messagebox.showwarning('提示', '需要发送的附件不能大于2M，否则会发生错误！')
            return
        # 得到文件名和文件后缀名
        filename, suffix = str(filepath).split('/')[-1].split('.')
        # 将附件添加到msg容器中，等会进行发送
        with open(filepath, 'rb') as f:
            mime = MIMEBase(filename, suffix, filename=filename + '.' + suffix)
            mime.add_header('Content-Disposition', 'attachment', filename=('gb2312' , '', filename + '.' + suffix))
            mime.add_header('Content-ID', '<0>')
            mime.add_header('X-Attachment-Id', '0')
            mime.set_payload(f.read())
            encode_base64(mime)
            self.msg.attach(mime)

        messagebox.showinfo('添加成功', filename + '.' + suffix + '添加成功')

    def _format_addr(self, s):
        name, addr = parseaddr(s)
        return formataddr((Header(name, 'utf-8').encode(), addr))

    # 发送函数
    def send(self):
        try:
            # 进行判断主要信息是否填写完整
            if self.From_addr_text.get() == '' or self.From_pw_text.get() == '' or self.To_addr_text.get() == '':
                messagebox.showinfo('错误', '信息填写不完整，请补全！')
                return

            self.msg.attach(MIMEText('<pre>' + self.content.get(0.0, END) + '</pre>' +
                                     '<br><br><br><br><br><p align="right">————发送自Python脚本客户端</p>', 'html', 'utf-8'))

            from_addr = self.From_addr_text.get()+self.FromserverChosen.get()
            self.msg['From'] = self._format_addr('Python爱好者 <%s>' % from_addr)
            to_addr = self.To_addr_text.get()+self.Toserver.get()
            self.msg['To'] = self._format_addr('管理员 <%s>' % to_addr)
            self.msg['Subject'] = Header(self.subject_text.get(), 'utf-8').encode()

            self.port = 'smtp.' + str(self.FromserverChosen.get())[1:].split('.')[0] + '.com'
            svr = smtplib.SMTP(self.port, 25)
            svr.set_debuglevel(True)
            svr.starttls()
            svr.login(self.From_addr_text.get() + self.FromserverChosen.get(), self.From_pw_text.get())
            svr.sendmail(self.From_addr_text.get() + self.FromserverChosen.get(), [self.To_addr_text.get() + self.Toserver.get()], self.msg.as_string())
            svr.quit()
            messagebox.showinfo('发送成功', '恭喜，邮件发送成功！！！')
        except:
            messagebox.showerror('出现错误', '对不起，发生了错误，发送失败，请重试！！！')

root = Tk()
Smtp(root)
mainloop()
